Análisis de los factores que influyen en la decisión de compra de vivienda a nivel internacional
2025-11-06
- 1. Introducción
- 2. Análisis exploratorio de los datos
- 3. Contraste de hipótesis y estadística inferencial
- 4. PCA: Análisis de Componentes Principales
1. Introducción
La compra de vivienda es uno de los procesos financieros más importantes para los individuos y familias en todo el mundo. Para la mayoría de compradores, esta adquisición se realiza a través de un préstamo hipotecario, por lo que las instituciones financieras evalúan múltiples factores para determinar si un solicitante es elegible para un crédito y bajo qué condiciones.
El mercado inmobiliario global es un sector clave en la economía, moviendo miles de millones de dólares anualmente. La correcta evaluación del perfil financiero del comprador, junto con las características del inmueble, es fundamental tanto para garantizar el acceso a la vivienda como para reducir el riesgo económico de las entidades financieras.
1.1 Obtención de los datos
El set de datos fue obtenido de la plataforma Kaggle y contiene información global sobre compras de vivienda y decisiones de aprobación hipotecaria. Incluye 200,000 registros (muestras) con 25 variables relacionadas tanto con la propiedad como con el comprador y su historial financiero.
El objetivo principal de este estudio es realizar un análisis estadístico para comprender qué factores influyen en la aprobación o rechazo de un préstamo hipotecario. Asimismo, se buscará identificar qué características del comprador y de la propiedad tienen mayor peso en la decisión final y desarrollar modelos predictivos que permitan anticipar el resultado de aprobación crediticia.
1.2 Metodología
A lo largo de este trabajo, se pretenden analizar las siguientes preguntas:
- ¿Qué variables explican mejor el precio de una vivienda?
- ¿Influyen el país, tipo de propiedad, tamaño, número de habitaciones o el estado de mobiliario?
- ¿Qué relación existe entre el precio y variables como el salario del comprador, el número de propietarios anteriores o el año de construcción?
- ¿Qué factores determinan la decisión de compra (variable
decision)?
- ¿Qué peso tienen variables como el ratio EMI/income, el nivel de satisfacción (satisfaction_score), el rating del vecindario (neighbourhood_rating) o la conectividad (connectivity_score)?
- ¿Se puede predecir la decisión de compra con un modelo de clasificación?
- ¿Existen diferencias significativas entre países o ciudades en
cuanto a precios y decisiones de compra?
- ¿Qué países tienen precios más altos en promedio?
- ¿Hay diferencias en la tasa de compra (decision = 1) entre regiones?
- ¿Cómo se distribuye el precio de las viviendas y hasta qué punto
es posible predecirlo con modelos estadísticos y de machine
learning?
- ¿Se ajusta a una distribución teórica conocida (gamma, log-normal, normal)?
- ¿Qué modelo de regresión (lineal, regularizado o de machine learning) ofrece mejor rendimiento en la predicción del precio?
- ¿Qué variables son más relevantes en la estimación?
- ¿Qué insights se pueden extraer sobre el perfil del
comprador?
- ¿Qué relación hay entre salario, gastos mensuales, préstamo y decisión de compra?
- ¿Influyen los aspectos legales (legal_cases_on_property) o de seguridad (crime_cases_reported)?
El análisis se llevará a cabo en dos fases principales:
Volumen 1: Análisis Exploratorio y Estadístico
- Importación de librerías y datos
- Resumen estadístico general
- Visualización de datos
- Contraste de hipótesis y estadística inferencial
- PCA: Análisis de Componentes Principales
- Varianza explicada
- Componentes principales
- Varianza explicada
Volumen 2: Machine Learning
- Modelo para la decisión de compra (clasificación)
- Modelo para el precio de la vivienda
- Interpretación de resultados
- Conclusiones y limitaciones
- Referencias
1.3 Variables del dataset
El conjunto de datos Global House Purchase Decision Dataset contiene información detallada sobre propiedades residenciales, características del entorno y perfil financiero de los compradores. En total, incluye 200.000 observaciones y 25 variables, que permiten analizar los factores que influyen en la decisión de compra.
A continuación, se describen las variables incluidas en el dataset:
property_id: Identificador único de cada propiedad.country: País donde se encuentra la propiedad.
city: Ciudad en la que está ubicada la vivienda.
property_type: Tipo de propiedad.furnishing_status: Nivel de amueblado del inmueble.
property_size_sqft: Tamaño total de la propiedad en pies cuadrados.price: Precio de la vivienda en dólares estadounidenses (USD).
constructed_year: Año en el que se construyó la propiedad.previous_owners: Número de propietarios previos.rooms: Número de dormitorios de la vivienda.
bathrooms: Número de baños de la vivienda.garage: Indica si la propiedad dispone de garaje propio (variable binaria: 1 = sí, 0 = no).garden: Indica si la propiedad cuenta con jardín o espacio exterior privado (variable binaria: 1 = sí, 0 = no).crime_cases_reported: Número de crímenes reportados en la zona (indicador de seguridad).legal_cases_on_property: Número de casos legales asociados a la propiedad.customer_salary: Salario del comprador (en USD).
loan_amount: Monto solicitado del préstamo hipotecario.
loan_tenure_years: Duración del préstamo en años.
monthly_expenses: Gastos mensuales promedio del comprador.down_payment: Cantidad inicial que el comprador aporta en efectivo para la compra, antes del préstamo hipotecario.emi_to_income_ratio: Relación entre la cuota mensual del préstamo (EMI, Equated Monthly Installment) y el ingreso mensual del comprador.satisfaction_score: Puntuación de satisfacción subjetiva del comprador (escala 1–10).neighbourhood_rating: Puntuación de la zona o vecindario (escala 1-10).connectivity_score: Medida de accesibilidad y transporte de la propiedad (escala 1-10).decision: Variable objetivo binaria: 1 = Compra aprobada / 0 = No compra.
2. Análisis exploratorio de los datos
2.1 Importar datos y librerías
library(dplyr)
library(ggplot2)
library(tidyr)
library(corrplot)
library(scales)
library(broom)
library(car)
data <- read.csv('./global_house_purchase_dataset.csv')
glimpse(data)## Rows: 200,000
## Columns: 25
## $ property_id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,…
## $ country <chr> "France", "South Africa", "South Africa", "Ger…
## $ city <chr> "Marseille", "Cape Town", "Johannesburg", "Fra…
## $ property_type <chr> "Farmhouse", "Apartment", "Farmhouse", "Farmho…
## $ furnishing_status <chr> "Semi-Furnished", "Semi-Furnished", "Semi-Furn…
## $ property_size_sqft <int> 991, 1244, 4152, 3714, 531, 3169, 1986, 4048, …
## $ price <int> 412935, 224538, 745104, 1110959, 99041, 110736…
## $ constructed_year <int> 1989, 1990, 2019, 2008, 2007, 1985, 1976, 2020…
## $ previous_owners <int> 6, 4, 5, 1, 6, 0, 1, 4, 6, 2, 4, 2, 4, 6, 6, 1…
## $ rooms <int> 6, 8, 2, 3, 3, 5, 2, 6, 2, 5, 8, 3, 2, 7, 3, 8…
## $ bathrooms <int> 2, 8, 1, 3, 3, 2, 1, 6, 1, 2, 3, 1, 2, 2, 1, 6…
## $ garage <int> 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0…
## $ garden <int> 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1…
## $ crime_cases_reported <int> 1, 1, 0, 0, 3, 0, 0, 1, 0, 0, 1, 4, 2, 6, 0, 1…
## $ legal_cases_on_property <int> 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1…
## $ customer_salary <int> 10745, 16970, 21914, 17980, 17676, 95520, 1142…
## $ loan_amount <int> 193949, 181465, 307953, 674720, 65833, 793316,…
## $ loan_tenure_years <int> 15, 20, 30, 15, 25, 30, 25, 20, 15, 10, 25, 20…
## $ monthly_expenses <int> 6545, 8605, 2510, 8805, 8965, 10615, 14440, 72…
## $ down_payment <int> 218986, 43073, 437151, 436239, 33208, 314052, …
## $ emi_to_income_ratio <dbl> 0.16, 0.08, 0.09, 0.33, 0.03, 0.05, 0.16, 0.13…
## $ satisfaction_score <int> 1, 9, 6, 2, 3, 10, 9, 1, 8, 1, 8, 2, 3, 6, 1, …
## $ neighbourhood_rating <int> 5, 1, 8, 6, 3, 8, 10, 5, 8, 4, 7, 5, 7, 9, 2, …
## $ connectivity_score <int> 6, 2, 1, 6, 4, 2, 10, 8, 10, 7, 6, 6, 2, 1, 7,…
## $ decision <int> 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0…
- ¿Hay valores faltantes? ¿Y duplicados?
sum(is.na(data))## [1] 0
sum(duplicated(data))## [1] 0
2.2 Resumen estadístico general
data %>%
select_if(is.numeric) %>%
summary()## property_id property_size_sqft price constructed_year
## Min. : 1 Min. : 400 Min. : 56288 Min. :1960
## 1st Qu.: 50001 1st Qu.:1802 1st Qu.: 565990 1st Qu.:1975
## Median :100001 Median :3190 Median :1023429 Median :1991
## Mean :100001 Mean :3196 Mean :1215365 Mean :1991
## 3rd Qu.:150000 3rd Qu.:4589 3rd Qu.:1725556 3rd Qu.:2008
## Max. :200000 Max. :6000 Max. :4202732 Max. :2023
## previous_owners rooms bathrooms garage
## Min. :0.000 Min. :1.000 Min. :1.00 Min. :0.0000
## 1st Qu.:1.000 1st Qu.:3.000 1st Qu.:1.00 1st Qu.:0.0000
## Median :3.000 Median :5.000 Median :2.00 Median :0.0000
## Mean :3.001 Mean :4.514 Mean :2.76 Mean :0.4994
## 3rd Qu.:5.000 3rd Qu.:7.000 3rd Qu.:4.00 3rd Qu.:1.0000
## Max. :6.000 Max. :8.000 Max. :8.00 Max. :1.0000
## garden crime_cases_reported legal_cases_on_property customer_salary
## Min. :0.0000 Min. : 0.000 Min. :0.0000 Min. : 2000
## 1st Qu.:0.0000 1st Qu.: 0.000 1st Qu.:0.0000 1st Qu.: 21450
## Median :1.0000 Median : 1.000 Median :0.0000 Median : 41465
## Mean :0.5002 Mean : 1.229 Mean :0.2489 Mean : 46529
## 3rd Qu.:1.0000 3rd Qu.: 2.000 3rd Qu.:0.0000 3rd Qu.: 70805
## Max. :1.0000 Max. :10.000 Max. :1.0000 Max. :100000
## loan_amount loan_tenure_years monthly_expenses down_payment
## Min. : 23504 Min. :10.00 Min. : 500 Min. : 8966
## 1st Qu.: 337280 1st Qu.:15.00 1st Qu.: 5770 1st Qu.: 184959
## Median : 626932 Median :20.00 Median :10520 Median : 356170
## Mean : 759758 Mean :19.99 Mean :10560 Mean : 455607
## 3rd Qu.:1058416 3rd Qu.:25.00 3rd Qu.:15260 3rd Qu.: 625735
## Max. :3520150 Max. :30.00 Max. :20000 Max. :2492723
## emi_to_income_ratio satisfaction_score neighbourhood_rating connectivity_score
## Min. :0.0000 Min. : 1.000 Min. : 1.000 Min. : 1.000
## 1st Qu.:0.0700 1st Qu.: 3.000 1st Qu.: 3.000 1st Qu.: 3.000
## Median :0.1300 Median : 5.000 Median : 5.000 Median : 5.000
## Mean :0.1954 Mean : 5.499 Mean : 5.505 Mean : 5.496
## 3rd Qu.:0.2400 3rd Qu.: 8.000 3rd Qu.: 8.000 3rd Qu.: 8.000
## Max. :3.4600 Max. :10.000 Max. :10.000 Max. :10.000
## decision
## Min. :0.0000
## 1st Qu.:0.0000
## Median :0.0000
## Mean :0.2303
## 3rd Qu.:0.0000
## Max. :1.0000
sapply(data %>% select(where(is.character)), n_distinct)## country city property_type furnishing_status
## 13 40 6 3
2.3 Visualización de datos
Distribución de la
variable decision
data %>%
count(decision) %>%
mutate(pct = n/sum(n)*100,
decision = factor(decision, labels = c("No compra", "Compra"))) %>%
ggplot(aes(x = decision, y = pct, fill = decision)) +
geom_col() +
geom_text(aes(label = sprintf("%.2f%%", pct)),
vjust = 1.5, color = "black", size = 4) +
labs(title = "Distribución de la decisión de compra",
x = "Decisión", y = "%") +
scale_fill_manual(values = c("#F8766D", "#00BA38")) +
theme_minimal() +
theme(legend.position = "none")El gráfico representa la distribución porcentual de la variable decision, que indica si un cliente decide o no comprar una vivienda. Se observa un desequilibrio marcado entre ambas categorías: el 76.97% de los individuos no realiza la compra, mientras que solo el 23.03% decide concretarla.
Esta distribución desequilibrada es un aspecto importante a considerar, ya que puede influir en el rendimiento de los modelos predictivos.
Distribución del precio
ggplot(data, aes(x = price)) +
geom_histogram(fill = "#69b3a2", color = "white", bins = 40) +
scale_x_continuous(labels = comma) +
labs(title = "Distribución del precio de las viviendas",
x = "Precio (USD)", y = "Frecuencia") +
theme_minimal()El histograma muestra la distribución del precio de las viviendas en dólares estadounidenses (USD). Se observa una distribución asimétrica a la derecha, parecida a una distribución gamma, lo que indica que la mayoría de los inmuebles se concentran en los rangos de precios más bajos, mientras que un número reducido de propiedades presenta precios considerablemente más altos.
La mayor frecuencia de viviendas se sitúa aproximadamente entre los 500,000 y 1,000,000 USD, reflejando que este rango constituye el segmento más representativo del mercado analizado. A partir de valores superiores a los 2 millones de dólares, la frecuencia disminuye progresivamente, mostrando la presencia de propiedades de lujo que elevan la cola derecha de la distribución.
A continuación, aplicaremos una transformación logarítmica al precio con el objetivo de aproximar su distribución a una normal.
data <- data %>% mutate(log_price = log(price))
ggplot(data, aes(x = log_price)) +
geom_histogram(fill = "#69b3a2", color = "white", bins = 40) +
scale_x_continuous() +
labs(title = "Distribución del logaritmo del precio de las viviendas",
x = "Precio (USD)", y = "Frecuencia") +
theme_minimal()Tras aplicar la transformación logarítmica al precio de las viviendas, se observa que la distribución se aproxima más a una distribución normal, corrigiendo la fuerte asimetría a la derecha presente en los valores originales.
Distribución del precio por país y por tipo de propiedad
# Boxplot de precios por país
data %>%
ggplot(aes(x = country, y = price)) +
geom_boxplot(fill = "#56B4E9", outlier.alpha = 0.2) +
coord_flip() +
scale_y_continuous(labels = comma) +
labs(title = "Distribución del precio por país (Top 10)",
x = "País", y = "Precio (USD)") +
theme_minimal()En este gráfico se aprecia que Singapur, Emiratos Árabes Unidos (UAE), Japón y Estados Unidos presentan los precios medianos más altos, así como una mayor dispersión, lo que refleja mercados con viviendas de alto valor y mayor desigualdad de precios. En contraste, países como Brasil, India y Sudáfrica muestran precios sustancialmente más bajos y con menor variabilidad, indicando mercados más accesibles y homogéneos.
# Boxplot de precios por tipo de propiedad
data %>%
ggplot(aes(x = property_type, y = price)) +
geom_boxplot(fill = "#56B4E9", outlier.alpha = 0.2) +
scale_y_continuous(labels = comma) +
coord_flip() +
labs(title = "Distribución del precio por tipo de propiedad (Top 10)",
x = "Propiedad", y = "Precio (USD)") +
theme_minimal()Por otro lado, el boxplot por tipo de propiedad evidencia que no hay diferencias estructurales dentro de cada mercado. Si bien es cierto que hay propiedades muy caras (outliers) en todos los tipos de propiedades, las distribuciones centrales son bastante similares, sin diferencias estructurales marcadas entre categorías.
Relaciones entre variables numéricas
# Seleccionar variables numéricas relevantes
num_vars <- data %>%
select_if(is.numeric) %>%
select(-property_id)
# Matriz de correlación
corr_matrix <- cor(num_vars)
corrplot(corr_matrix, method = "color", type = "upper", tl.col = "black", order = "hclust")El análisis de las relaciones entre las variables numéricas revela patrones coherentes con el comportamiento esperado en un contexto inmobiliario.
En primer lugar, se observa una correlación positiva entre el precio
de la vivienda y el tamaño del inmueble
(property_size_sqft), lo cual es lógico, ya que las
propiedades de mayor superficie tienden a tener precios más altos.
Asimismo, variables como el salario del comprador
(customer_salary), la cantidad inicial que el comprador
aporta (down_payment) y el monto del préstamo
(loan_amount) muestran también una relación directa con el
precio, reflejando que los compradores con mayor capacidad económica
tienden a adquirir viviendas más costosas.
En cuanto a correlaciones negativas, vemos una relación lógica entre
customer_salary y emi_to_income_ratio: cuanto
mayor es el salario del comprador, menor es la proporción que representa
la cuota mensual del préstamo respecto a sus ingresos. Esto es
coherente, ya que un ingreso alto diluye el peso relativo de la cuota
hipotecaria, mejorando la capacidad de pago.
Además, existe una correlación negativa interesante entre
legal_cases_on_property y decision. Esto
significa que, a medida que aumentan los casos legales asociados a una
propiedad, disminuye la probabilidad de que la decisión final sea
positiva (compra aprobada).
Relaciones bivariantes
# Salario vs Decisión de compra
data %>%
mutate(decision = factor(decision, labels = c("No compra", "Compra"))) %>%
ggplot(aes(x = decision, y = customer_salary, fill = decision)) +
geom_boxplot(outlier.alpha = 0.2) +
scale_fill_manual(values = c("#F8766D", "#00BA38")) +
labs(title = "Salario según decisión de compra",
x = "Decisión", y = "Salario del cliente") +
theme_minimal() +
theme(legend.position = "none")# Número de crímenes reportados vs Precio medio
data %>%
group_by(crime_cases_reported) %>%
summarise(mean_price = mean(price, na.rm = TRUE)) %>%
ggplot(aes(x = factor(crime_cases_reported), y = mean_price)) +
geom_col(fill = "#56B4E9") +
scale_y_continuous(labels = comma) +
labs(title = "Precio medio según el número de crímenes reportados",
x = "Número de crímenes", y = "Precio medio (USD)") +
theme_minimal()El análisis de las relaciones bivariantes permite identificar cómo ciertas variables influyen directamente en la decisión de compra y en el precio de la vivienda.
En primer lugar, se observa que el salario del cliente
(customer_salary) presenta una relación positiva con la
decisión de compra.
Por otra parte, la relación entre el número de crímenes reportados
(crime_cases_reported) y el precio medio de las viviendas
muestra una tendencia inversa: los precios disminuyen a medida que
aumenta la incidencia delictiva.
Decisión de compra por país
# ¿Qué porcentaje de personas toma la decisión de comprar una vivienda en cada país?
data %>%
group_by(country) %>%
summarise(pct_purchase = mean(decision) * 100) %>%
arrange(desc(pct_purchase)) %>%
slice_head(n = 10) %>%
ggplot(aes(x = reorder(country, pct_purchase), y = pct_purchase)) +
geom_col(fill = "#009E73") +
geom_text(aes(label = sprintf("%.2f%%", pct_purchase)),
hjust = 1.2, color = "white", size = 4) +
coord_flip() +
labs(title = "Porcentaje de decisión de compra por país (Top 10)",
x = "País", y = "% de compras") +
theme_minimal()El análisis de la decisión de compra por país revela diferencias significativas en el comportamiento de los compradores según su ubicación geográfica.
Se observa que algunos países presentan una mayor proporción de decisiones de compra positivas, lo que puede estar relacionado con factores como la estabilidad económica, el nivel de ingresos promedio o las características del mercado inmobiliario local.
3. Contraste de hipótesis y estadística inferencial
En esta sección se pretende verificar estadísticamente algunas de las relaciones sugeridas en el análisis exploratorio previo. Para ello, se formulan hipótesis estadísticas y se aplican pruebas de contraste adecuadas según el tipo de variable y la distribución observada.
3.1 Diferencias de precio entre países
Hipótesis:
- H0: El precio medio es igual entre los países.
- H1: Al menos un país presenta un precio medio distinto.
# Test de normalidad
shapiro.test(sample(data$log_price, 5000))##
## Shapiro-Wilk normality test
##
## data: sample(data$log_price, 5000)
## W = 0.96749, p-value < 2.2e-16
El test de Shapiro–Wilk, aplicado a una muestra aleatoria de la
variable log_price, muestra un p-value < 2.2e-16, lo que
sugiere que la variable transformada no sigue una distribución normal
perfecta. No obstante, dado el gran tamaño muestral, el ANOVA resulta
suficientemente robusto frente a desviaciones de normalidad, por lo que
la ligera falta de ajuste no compromete la validez del análisis.
A continuación, se realiza la prueba de Levene para ver si las varianzas entre países son homogéneas o no, y esto nos indicará si podemos utilizar el test paramétrico de ANOVA o, en caso contrario, el de Kruskal-Wallis.
# Test de homogeneidad de varianzas
leveneTest(log_price ~ factor(country), data = data)## Levene's Test for Homogeneity of Variance (center = median)
## Df F value Pr(>F)
## group 12 1.4727 0.126
## 199987
El resultado (p = 0.126) sugiere que no existe evidencia suficiente para rechazar la hipótesis nula de igualdad de varianzas, cumpliéndose así el supuesto de homocedasticidad. Por ello, se aplicó un ANOVA clásico para comparar el precio medio entre países usando la variable transformada.
# ANOVA
anova_country <- aov(log_price ~ factor(country), data = data)
summary(anova_country)## Df Sum Sq Mean Sq F value Pr(>F)
## factor(country) 12 38869 3239 7414 <2e-16 ***
## Residuals 199987 87373 0
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
El ANOVA realizado sobre el precio de la vivienda en su escala logarítmica revela diferencias estadísticamente significativas entre países. El modelo muestra un p-value < 2e-16, lo que indica que la variación del precio medio de las viviendas difiere de forma sustancial según el país.
Ahora llevaremos a cabo el test de Tukey para ver qué países difieren entre sí en el precio medio. Este test incluye una corrección automática del error familiar (FWER), garantizando que la probabilidad de obtener falsos positivos se mantenga controlada al realizar múltiples comparaciones simultáneas.
# Post-hoc Tukey
tukey <- TukeyHSD(anova_country)
tukey## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = log_price ~ factor(country), data = data)
##
## $`factor(country)`
## diff lwr upr p adj
## Brazil-Australia -0.47616460 -0.50110219 -0.45122702 0e+00
## Canada-Australia 0.07412258 0.04918662 0.09905854 0e+00
## China-Australia 0.17005499 0.14517333 0.19493665 0e+00
## France-Australia 0.26375468 0.23890955 0.28859980 0e+00
## Germany-Australia -0.07306215 -0.09799528 -0.04812902 0e+00
## India-Australia -0.76989040 -0.79484424 -0.74493656 0e+00
## Japan-Australia 0.32866878 0.30369861 0.35363896 0e+00
## Singapore-Australia 0.77667016 0.75168399 0.80165633 0e+00
## South Africa-Australia -0.59123686 -0.61617282 -0.56630089 0e+00
## UAE-Australia 0.61147800 0.58643507 0.63652092 0e+00
## UK-Australia 0.21916180 0.19423070 0.24409290 0e+00
## USA-Australia 0.44443000 0.41944507 0.46941494 0e+00
## Canada-Brazil 0.55028718 0.52533303 0.57524134 0e+00
## China-Brazil 0.64621959 0.62131970 0.67111948 0e+00
## France-Brazil 0.73991928 0.71505590 0.76478266 0e+00
## Germany-Brazil 0.40310245 0.37815114 0.42805377 0e+00
## India-Brazil -0.29372580 -0.31869781 -0.26875378 0e+00
## Japan-Brazil 0.80483339 0.77984505 0.82982172 0e+00
## Singapore-Brazil 1.25283476 1.22783044 1.27783908 0e+00
## South Africa-Brazil -0.11507225 -0.14002640 -0.09011810 0e+00
## UAE-Brazil 1.08764260 1.06258156 1.11270363 0e+00
## UK-Brazil 0.69532640 0.67037711 0.72027570 0e+00
## USA-Brazil 0.92059461 0.89559152 0.94559769 0e+00
## China-Canada 0.09593241 0.07103414 0.12083067 0e+00
## France-Canada 0.18963210 0.16477034 0.21449385 0e+00
## Germany-Canada -0.14718473 -0.17213443 -0.12223504 0e+00
## India-Canada -0.84401298 -0.86898338 -0.81904259 0e+00
## Japan-Canada 0.25454620 0.22955949 0.27953292 0e+00
## Singapore-Canada 0.70254758 0.67754488 0.72755028 0e+00
## South Africa-Canada -0.66535944 -0.69031197 -0.64040691 0e+00
## UAE-Canada 0.53735541 0.51229599 0.56241484 0e+00
## UK-Canada 0.14503922 0.12009154 0.16998689 0e+00
## USA-Canada 0.37030742 0.34530595 0.39530889 0e+00
## France-China 0.09369969 0.06889240 0.11850698 0e+00
## Germany-China -0.24311714 -0.26801256 -0.21822171 0e+00
## India-China -0.93994539 -0.96486156 -0.91502922 0e+00
## Japan-China 0.15861380 0.13368127 0.18354632 0e+00
## Singapore-China 0.60661517 0.58166663 0.63156372 0e+00
## South Africa-China -0.76129184 -0.78619011 -0.73639358 0e+00
## UAE-China 0.44142301 0.41641762 0.46642840 0e+00
## UK-China 0.04910681 0.02421341 0.07400021 0e+00
## USA-China 0.27437502 0.24942770 0.29932233 0e+00
## Germany-France -0.33681683 -0.36167574 -0.31195792 0e+00
## India-France -1.03364508 -1.05852477 -1.00876539 0e+00
## Japan-France 0.06491411 0.04001804 0.08981017 0e+00
## Singapore-France 0.51291548 0.48800337 0.53782759 0e+00
## South Africa-France -0.85499153 -0.87985329 -0.83012978 0e+00
## UAE-France 0.34772332 0.32275428 0.37269235 0e+00
## UK-France -0.04459288 -0.06944976 -0.01973600 2e-07
## USA-France 0.18067533 0.15576445 0.20558620 0e+00
## India-Germany -0.69682825 -0.72179582 -0.67186069 0e+00
## Japan-Germany 0.40173094 0.37674705 0.42671482 0e+00
## Singapore-Germany 0.84973231 0.82473244 0.87473218 0e+00
## South Africa-Germany -0.51817470 -0.54312440 -0.49322501 0e+00
## UAE-Germany 0.68454015 0.65948355 0.70959675 0e+00
## UK-Germany 0.29222395 0.26727911 0.31716879 0e+00
## USA-Germany 0.51749216 0.49249351 0.54249080 0e+00
## Japan-India 1.09855919 1.07355463 1.12356375 0e+00
## Singapore-India 1.54656056 1.52154003 1.57158109 0e+00
## South Africa-India 0.17865355 0.15368315 0.20362394 0e+00
## UAE-India 1.38136840 1.35629118 1.40644561 0e+00
## UK-India 0.98905220 0.96408666 1.01401774 0e+00
## USA-India 1.21432041 1.18930110 1.23933971 0e+00
## Singapore-Japan 0.44800138 0.42296456 0.47303820 0e+00
## South Africa-Japan -0.91990564 -0.94489236 -0.89491892 0e+00
## UAE-Japan 0.28280921 0.25771575 0.30790267 0e+00
## UK-Japan -0.10950699 -0.13448885 -0.08452512 0e+00
## USA-Japan 0.11576122 0.09072563 0.14079681 0e+00
## South Africa-Singapore -1.36790702 -1.39290972 -1.34290431 0e+00
## UAE-Singapore -0.16519216 -0.19030154 -0.14008278 0e+00
## UK-Singapore -0.55750836 -0.58250622 -0.53251051 0e+00
## USA-Singapore -0.33224016 -0.35729170 -0.30718861 0e+00
## UAE-South Africa 1.20271485 1.17765543 1.22777427 0e+00
## UK-South Africa 0.81039865 0.78545098 0.83534633 0e+00
## USA-South Africa 1.03566686 1.01066539 1.06066833 0e+00
## UK-UAE -0.39231620 -0.41737078 -0.36726161 0e+00
## USA-UAE -0.16704799 -0.19215614 -0.14193984 0e+00
## USA-UK 0.22526821 0.20027158 0.25026483 0e+00
sum(tukey[["factor(country)"]][, "p adj"]>0.05)## [1] 0
El test post-hoc de Tukey mostró diferencias significativas entre todos los pares de países (p-value < 0.05), confirmando que el país de localización es un factor determinante en el precio de la vivienda.
3.2 Factores que influyen en la decisión de compra
data$decision <- as.factor(data$decision)
model1 <- glm(decision ~ log_price + factor(country) +
satisfaction_score + bathrooms + rooms +
previous_owners, data
= data, family = binomial)
summary(model1)##
## Call:
## glm(formula = decision ~ log_price + factor(country) + satisfaction_score +
## bathrooms + rooms + previous_owners, family = binomial, data = data)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -2.071e+00 1.445e-01 -14.338 < 2e-16 ***
## log_price -3.119e-01 1.035e-02 -30.145 < 2e-16 ***
## factor(country)Brazil -9.601e-01 3.608e-02 -26.608 < 2e-16 ***
## factor(country)Canada -2.306e-02 3.437e-02 -0.671 0.5024
## factor(country)China -7.392e-03 3.430e-02 -0.215 0.8294
## factor(country)France -2.761e-02 3.441e-02 -0.802 0.4223
## factor(country)Germany -8.422e-03 3.427e-02 -0.246 0.8059
## factor(country)India -6.797e-01 3.579e-02 -18.992 < 2e-16 ***
## factor(country)Japan -6.311e-02 3.464e-02 -1.822 0.0684 .
## factor(country)Singapore -2.200e-01 3.584e-02 -6.138 8.38e-10 ***
## factor(country)South Africa -9.945e-01 3.616e-02 -27.505 < 2e-16 ***
## factor(country)UAE -1.008e-01 3.529e-02 -2.855 0.0043 **
## factor(country)UK 2.721e-03 3.440e-02 0.079 0.9369
## factor(country)USA -6.912e-01 3.606e-02 -19.166 < 2e-16 ***
## satisfaction_score 7.879e-01 3.956e-03 199.167 < 2e-16 ***
## bathrooms -3.584e-03 4.799e-03 -0.747 0.4551
## rooms 3.335e-05 3.849e-03 0.009 0.9931
## previous_owners 4.900e-03 3.441e-03 1.424 0.1544
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 215875 on 199999 degrees of freedom
## Residual deviance: 131859 on 199982 degrees of freedom
## AIC: 131895
##
## Number of Fisher Scoring iterations: 6
coef_plot <- tidy(model1) %>%
filter(term != "(Intercept)") %>%
mutate(signif = ifelse(p.value < 0.05, "*", ""),
term = paste0(term, signif),
term = reorder(term, estimate))
ggplot(coef_plot, aes(x = term, y = estimate)) +
geom_point() +
geom_errorbar(aes(ymin = estimate - std.error, ymax =
estimate + std.error),
width = 0.2) +
coord_flip() +
theme_minimal() +
labs(title = "Efecto de las variables en la probabilidad de
compra",
x = "Variables", y = "Coeficiente")El modelo de regresión logística muestra que la decisión de compra está influida principalmente por el precio de la vivienda (en su escala logarítmica), el país donde se ubica el inmueble y el nivel de satisfacción del comprador. En particular, se observa que el coeficiente de log_price es negativo y altamente significativo (p-value < 2e-16), lo que indica que, a medida que el precio aumenta, la probabilidad de que el comprador decida adquirir la vivienda disminuye. Este resultado sugiere que la capacidad económica es un factor limitante importante en la decisión.
La variable satisfaction_score presenta un efecto positivo y muy significativo (p-value < 2e-16), implicando que un mayor nivel de satisfacción incrementa considerablemente la probabilidad de compra. Este resultado destaca el papel de la percepción personal y la valoración emocional del inmueble en la toma de decisiones, además de los factores económicos.
En cuanto al país de residencia, se identifican diferencias significativas entre mercados. Los compradores en Brasil, India, Sudáfrica, Singapur, Emiratos Árabes Unidos y Estados Unidos presentan probabilidades de compra significativamente menores en comparación con el país de referencia (Australia).
Por el contrario, variables relacionadas con las características
físicas del inmueble —como el número de baños (bathrooms),
de habitaciones (rooms) o de propietarios anteriores
(previous_owners)— no muestran efectos estadísticamente
significativos cuando se controlan las demás variables del modelo.
4. PCA: Análisis de Componentes Principales
El análisis de componentes principales (PCA) es clave para identificar los factores que explican la mayor parte de la variabilidad en nuestro conjunto de datos.
# PCA no admite factores ni variables categóricas
pca_data <- data %>%
select(property_size_sqft, price, log_price,constructed_year,
previous_owners, rooms, bathrooms, garage, garden,
crime_cases_reported, legal_cases_on_property,
customer_salary, loan_amount, loan_tenure_years,
monthly_expenses, down_payment, emi_to_income_ratio,
satisfaction_score, neighbourhood_rating,
connectivity_score)
pca_result <- prcomp(pca_data, scale. = TRUE)
summary(pca_result)## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6 PC7
## Standard deviation 2.0942 1.27540 1.26397 1.0120 1.01148 1.00432 1.00271
## Proportion of Variance 0.2193 0.08133 0.07988 0.0512 0.05116 0.05043 0.05027
## Cumulative Proportion 0.2193 0.30061 0.38049 0.4317 0.48285 0.53328 0.58356
## PC8 PC9 PC10 PC11 PC12 PC13 PC14
## Standard deviation 1.00140 1.00018 0.99891 0.99848 0.99727 0.99482 0.93835
## Proportion of Variance 0.05014 0.05002 0.04989 0.04985 0.04973 0.04948 0.04403
## Cumulative Proportion 0.63370 0.68371 0.73360 0.78345 0.83318 0.88266 0.92669
## PC15 PC16 PC17 PC18 PC19 PC20
## Standard deviation 0.66991 0.61111 0.56839 0.47014 0.3161 1.081e-14
## Proportion of Variance 0.02244 0.01867 0.01615 0.01105 0.0050 0.000e+00
## Cumulative Proportion 0.94913 0.96780 0.98395 0.99500 1.0000 1.000e+00
varianza_explicada <- pca_result$sdev^2 /sum(pca_result$sdev^2)
varianza_acumulada <- cumsum(varianza_explicada)
df_varianza <- data.frame(
Componente = 1:length(varianza_acumulada),
Varianza_Acumulada = varianza_acumulada
)
ggplot(df_varianza, aes(x = Componente, y = Varianza_Acumulada)) +
geom_line(color = "#0072B2", linewidth = 1) +
geom_point(color = "#0072B2", size = 2) +
geom_hline(yintercept = 0.80, linetype = "dashed", color = "red") +
theme_minimal() +
labs(title = "Varianza explicada acumulada",
x = "Número de Componentes",
y = "Varianza Acumulada") +
scale_x_continuous(breaks = df_varianza$Componente)Los resultados indican que el primer componente principal (PC1) captura una porción significativa de la varianza total, alrededor del 20%. Además, los primeros diez componentes en conjunto explican cerca del 70–75% de la variabilidad del conjunto de datos.
# Extraer scores de las dos primeras componentes
scores <- as.data.frame(pca_result$x[,1:2])
scores$country <- data$country
ggplot() +
geom_point(data = scores, aes(x = PC1, y = PC2, color =
country), alpha = 0.6) +
theme_minimal() +
labs(title = "Primeras dos componentes del PCA",
x = "PC1",
y = "PC2",
color = "País")# Qué variables contribuyen a PC1 y PC2
loadings <- as.data.frame(pca_result$rotation[,1:2])
loadings$variable <- rownames(loadings)
# Contribución para PC1
PC1_contrib_df <- loadings %>%
select(PC1) %>%
arrange(desc(PC1))
# Contribución para PC2
PC2_contrib_df <- loadings %>%
select(PC2) %>%
arrange(desc(PC2))
head(PC1_contrib_df, 5)## PC1
## price 0.4666070
## log_price 0.4553414
## loan_amount 0.4365345
## property_size_sqft 0.4033568
## down_payment 0.3986256
head(PC2_contrib_df, 5)## PC2
## rooms 0.705867249
## bathrooms 0.705777174
## emi_to_income_ratio 0.037967025
## property_size_sqft 0.009998963
## crime_cases_reported 0.009534732
PC1 está fuertemente asociado con el nivel económico y el tamaño de la propiedad. Las variables financieras (precio, cantidad de préstamo, pago inicial) y el tamaño del inmueble tienen cargas altas y positivas, lo que indica que este componente captura principalmente un gradiente de propiedades de mayor costo y mayor superficie frente a propiedades más económicas y pequeñas.
PC2 está dominado casi exclusivamente por la estructura interna del inmueble (número de habitaciones y baños). Estos dos atributos se mueven prácticamente de forma conjunta y definen la configuración habitacional del inmueble, independientemente del precio total.